#include "class.LinearAdapter.h"
#include <iostream>
using namespace std;

LinearAdapter::LinearAdapter()
{
    this->length = 0;
    this->head = NULL;
    this->foot = NULL;
}

LinearAdapter::~LinearAdapter(){}

Node* LinearAdapter::getHead()
{
    return this->head;
}

Node* LinearAdapter::getFoot()
{
    return this->foot;
}

Node* LinearAdapter::get(int pos)
{
    Node* ptr = head;
    if(pos >= this->length)return NULL;
    for(int i=0; i<pos; i++)
    {
        if(ptr->getNext() == NULL)return NULL;
        ptr = ptr->getNext();
    }
    return ptr;
}

bool LinearAdapter::insert(Node* node, int pos)
{
    if(pos >= length || pos < 0)return false;
    if(node == NULL)return false;
    // get the previous node
    Node* prevNode = NULL, *nextNode = NULL;
    pos == 0 || (prevNode = this->get(pos-1));
    // get the next node
    nextNode = this->get(pos);
    // link
    if(prevNode != NULL)prevNode->setNext(node);
    if(nextNode != NULL)nextNode->setPrev(node);
    node->setNext(nextNode);
    node->setPrev(prevNode);
    if(pos == 0)this->head = node;
    this->length++;
    return true;
}

bool LinearAdapter::append(Node* node)
{
    if(node == NULL)return false;
    if(this->length == 0)this->head = node;
    if(this->foot != NULL)this->foot->setNext(node);
    node->setPrev(this->foot);
    this->foot = node;
    this->length++;
    return true;
}

bool LinearAdapter::append(LinearAdapter* linearAdapter)
{
    if(linearAdapter->getLength() == 0)return false;
    this->foot->setNext(linearAdapter->getHead());
    linearAdapter->getHead()->setPrev(this->foot);
    this->foot = linearAdapter->getFoot();
    linearAdapter->clear();
    return true;
}

bool LinearAdapter::remove(int pos)
{
    if(pos < 0 || pos > this->getLength()-1)return false;
    Node* node = this->get(pos);
    if(node->getPrev() != NULL)node->getPrev()->setNext(node->getNext());
    if(node->getNext() != NULL)node->getNext()->setPrev(node->getPrev());
    delete node;
    this->length--;
    return true;
}

void LinearAdapter::sort()
{
    int* bodys = new int[this->getLength()];
    Node* node = head;
    for(int i=0; i < this->length; i++)
    {
        bodys[i] = node->getContent().c_str()[0];
        node = node->getNext();
        // cout << char(bodys[i]) << endl;
    }
    int maxVal = 0;
    int maxId = 0;
    int* rank = new int[this->getLength()];
    int ll = this->getLength();
    for(int i=0; i<this->getLength(); i++)
    {
        for(int j=0; j<ll; j++)
        {
            // maxVal > bodys[j] || ( (maxVal = bodys[j]) && (maxId = j) );
            if(maxVal < bodys[j])
            {
                maxVal = bodys[j];
                maxId = j;
            }
        }
        bodys[maxId] = -1;
        rank[i] = maxId;
        // cout << "val " << char(maxVal) << "," << maxId << endl;
        maxVal = 0;
    }
    ll = this->getLength();
    Node* nodes[ll];
    for(int i=0; i<ll; i++)
    {
        nodes[i] = this->get(rank[i]);
    }
    this->clear();
    for(int i=ll-1; i>=0; i--)
    {
        this->append(nodes[i]);
    }
    return;
}

int LinearAdapter::getLength()
{
    return this->length;
}

void LinearAdapter::clear()
{
    this->length = 0;
    this->head = NULL;
    this->foot = NULL;
}